package com.credithc.signature.manager.service.impl;

import cfca.seal.bean.CrossSealInfoBean;
import cfca.seal.bean.SealUserInfo;
import cfca.seal.bean.SignLocation;
import cfca.seal.util.FileUtil;
import cfca.seal.util.StrategyUtil;
import cfca.seal.util.StringUtil;
import cfca.seal.ws.SealClient;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.credithc.signature.common.constant.CoreConstant;
import com.credithc.signature.common.constant.ResponseEnum;
import com.credithc.signature.common.mapper.AdminMapper;
import com.credithc.signature.common.mapper.SealInfoMapper;
import com.credithc.signature.common.po.AdminRequest;
import com.credithc.signature.common.po.SealInfo;
import com.credithc.signature.common.to.CFCASignResult;
import com.credithc.signature.common.to.CommonResult;
import com.credithc.signature.common.utils.AmazonUtil;
import com.credithc.signature.common.utils.AmazonUtil2;
import com.credithc.signature.common.utils.DateUtil;
import com.credithc.signature.common.utils.UUIDUtil;
import com.credithc.signature.manager.constant.SealInfoConstant;
import com.credithc.signature.manager.constant.SealParamsConstant;
import com.credithc.signature.manager.constant.SignStatusConstant;
import com.credithc.signature.manager.ro.AdminReq;
import com.credithc.signature.manager.ro.ContractSealInfo;
import com.credithc.signature.manager.ro.CrossPageSealInfo;
import com.credithc.signature.manager.service.AdminService;
import com.credithc.signature.manager.service.FutureService;
import com.credithc.signature.manager.utils.HttpUploadUtil;
import com.credithc.signature.manager.utils.PdfRotationUtil;
import com.credithc.signature.manager.utils.ResponseUtil;
import com.google.common.io.Files;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.PdfTextExtractor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import sun.awt.image.BufferedImageGraphicsConfig;
import tk.mybatis.mapper.entity.Example;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;

@Service
@Slf4j
public class AdminServiceImpl implements AdminService {

    private static final String SNAP_PDF_PREFIX = "snapPdf_";
    private static final String WEB_PDF_URL_PREFIX = "/manual/contract/file/";
    private static final String WEB_PDF_FOLDER_PATH = "/data/temp/S3/";
    private static final String PDF_EXT = ".pdf";
    private static final Long THRESHOLD_TIME = 60L;
    private static final String SEQUENCE_KEY = "b9cf62d17f1c4523ad4945a4e03c273a";

    @Value("${signature.snapNoSignPdf.path:/data/temp/nosign-pdf/}")
    private String noSignPDFPath;

    @Value("${signature.snapSignPdf.path:/data/temp/sign-pdf/}")
    private String signPDFPath;

    @Value("${signature.tempImage.path:/data/temp/image/}")
    private String imagePath;

    @Value("${file.download.url:http://10.160.13.128/fs-api/downloadFile.hc?fsId=}")
    private String fastDfs_Download_path;

    @Value("${file.upload.url:http://10.160.13.128/fs-api/uploadFile.hc}")
    private String fastDfs_Upload_path;

    @Value("${signature.cfca.sealUrl:http://10.150.27.227:8091/Seal}")
    private String sealUrl;

    @Autowired
    AdminMapper adminMapper;

    @Autowired
    SealInfoMapper sealInfoMapper;

    @Autowired
    private FutureService futureService;


    /**
     * 校验请求时间是否过期
     *
     * @param adminReq
     * @return
     */
    @Override
    public boolean verifyTimestamp(AdminReq adminReq) {
        String nowTime = DateUtil.getDefaultAppointDateStr(new Date(System.currentTimeMillis()));
        String timestamp = DateUtil.getDefaultAppointDateStr(new Date(adminReq.getTimestamp()));
        long intervalTime = DateUtil.betweenNowSecond(new Date(adminReq.getTimestamp()));
        log.info("请求时间：" + timestamp);
        log.info("现在时间：" + nowTime);
        log.info("时间阀值：{}秒", THRESHOLD_TIME);
        log.info("时间间隔：{}秒", intervalTime);
        if (intervalTime > THRESHOLD_TIME) {
            return false;
        }
        return true;
    }

    /**
     * 校验数字签名
     *
     * @param adminReq
     * @return
     */
    @Override
    public boolean verifySignature(AdminReq adminReq) throws UnsupportedEncodingException {
        String signature = adminReq.getSignature();
        String systemSign = adminReq.getSystemSign();
        String requestNo = adminReq.getRequestNo();
        String sealId = adminReq.getSealId();
        String fileUrl = adminReq.getFileUrl();
        String originalCallbackUrl = adminReq.getCallbackUrl();
        log.info("originalCallbackUrl=" + originalCallbackUrl);
        String callbackUrl = URLDecoder.decode(originalCallbackUrl, "utf-8");
        log.info("decodeCallbackUrl=" + callbackUrl);
        String fileSys = adminReq.getFileSys();
        Long timestamp = adminReq.getTimestamp();

        StringBuilder builder = new StringBuilder();
        String str = builder.append(systemSign).append(requestNo).append(fileUrl).append(sealId).append(timestamp).append(callbackUrl).append(fileSys).append(SEQUENCE_KEY).toString();

        String value = DigestUtils.sha1Hex(str);
        if (!signature.equals(value)) {
            return false;
        }
        return true;
    }

    /**
     * 校验Token
     *
     * @param adminReq
     * @return
     */
    @Override
    public boolean verifyToken(AdminReq adminReq) {
        AdminRequest adminRequest = getAdminRequest(adminReq.getRequestNo(), adminReq.getToken());
        if (adminRequest == null) {
            return false;
        }
        return true;
    }

    /**
     * 校验版本回退接口请求参数
     *
     * @param adminReq
     * @return
     */
    @Override
    public CommonResult verifyParams(AdminReq adminReq) {
        if (StringUtil.isEmpty(adminReq.getRequestNo())) {
            return new CommonResult(false, "requestNo不能为空");
        }
        if (adminReq.getVersion() == null) {
            return new CommonResult(false, "版本号version不能为空");
        }
        if (adminReq.getVersion() <= 0) {
            return new CommonResult(false, "版本号version默认为1");
        }
        AdminRequest adminRequest = getAdminRequest(adminReq.getRequestNo(), adminReq.getToken());
        if (adminReq.getVersion() > adminRequest.getVersion()) {
            return new CommonResult(false, "回退版本不能小于当前数据库版本,当前数据库版本为[" + adminRequest.getVersion() + "]");
        }
        return new CommonResult(true, "校验成功");
    }

    /**
     * 版本回退方法
     * 版本为1 直接返回没有签章的PDF文件
     *
     * @param adminReq
     * @return
     */
    @Override
    public Object revoke(AdminReq adminReq) throws Exception {
        Integer revokeVersion = adminReq.getVersion();
        String requestNo = adminReq.getRequestNo();
        String token = adminReq.getToken();
        AdminRequest adminRequest = getAdminRequest(requestNo, token);
        if (adminRequest == null) {
            return new CommonResult(false, ResponseEnum.ILLEGAL_REQUESTNO.getCode());
        }
        Date date = new Date();
        switch (revokeVersion) {
            case 1:
                // 回退到未签章版本
                log.info("进入到回退初始版本代码.....");
                CommonResult commonResult = revokeToOriginalVersion(adminRequest);
                if (!commonResult.getIsSuccess()) {
                    log.error("行政章【版本回退接口】-->－消息－:requestSn={},版本回退失败：{}", requestNo, commonResult.getResult());
                    return ResponseUtil.getResponseMessageData((Integer) commonResult.getResult(), null);
                }
                log.info("行政章【版本回退接口】-->－消息－:requestSn={},版本回退成功-总耗时：{}秒", requestNo, DateUtil.betweenNowSecond(date));
                return ResponseUtil.getResponseMessageData(ResponseEnum.REVOKE_SUCCESS.getCode(), commonResult.getResult());
            default:
                // 回退到指定版本
                log.info("进入到回退到指定版本代码.....版本号={}", revokeVersion);
                adminReq.setSealType(adminRequest.getSealType());
                CommonResult commonResult1 = revokeToCustomVersion(adminReq, adminRequest, revokeVersion);
                if (!commonResult1.getIsSuccess()) {
                    log.error("行政章【版本回退接口】-->－消息－:requestSn={},版本回退失败：{}", requestNo, commonResult1.getResult());
                    HashMap data = new HashMap();
                    data.put("requestNo", requestNo);
                    data.put("errorMsg", commonResult1.getResult());
                    return ResponseUtil.getResponseMessageData(ResponseEnum.REVOKE_FAILED.getCode(), data);
                }
                log.info("行政章【版本回退接口】-->－消息－:requestSn={},版本回退成功-总耗时：{}秒", requestNo, DateUtil.betweenNowSecond(date));
                return ResponseUtil.getResponseMessageData(ResponseEnum.REVOKE_SUCCESS.getCode(), commonResult1.getResult());
        }
    }

    /**
     * 回退到未签章版本
     *
     * @param adminRequest
     * @return
     */
    private CommonResult revokeToOriginalVersion(AdminRequest adminRequest) {
        String requestNo = adminRequest.getRequestNo();
        String token = adminRequest.getToken();
        CommonResult commonResult = getContractPath(adminRequest);
        if (!commonResult.getIsSuccess()) {
            return new CommonResult(false, ResponseUtil.getResponseMessageData((Integer) commonResult.getResult(), null));
        }
        String downloadPath = commonResult.getResult().toString();

        // 获取返回压缩图片流
        String sealId = adminRequest.getSealId();
        CommonResult imageResult = getImages(requestNo, sealId);
        if (!imageResult.getIsSuccess()) {
            int code = (int) imageResult.getResult();
            return new CommonResult(false, ResponseUtil.getResponseMessageData(code, null));
        }

        // 返回结果
        HashMap data = new HashMap(16);
        data.put("fileUrl", buildWebFileUrl(requestNo, downloadPath));
        data.put("requestNo", requestNo);
        data.put("version", 1);
        data.put("sealImgs", imageResult.getResult());
        data.put("token", token);
        data.put("reSign", 1);

        // 删除以前的合同文件
        removeUnusedFile(requestNo, downloadPath, null);

        // 更新数据库状态
        adminRequest.setVersion(1);
        adminRequest.setVersionInfo("");
        updateRevokeInfo(adminRequest);

        return new CommonResult(true, data);
    }

    /**
     * 更新版本回退信息
     *
     * @param adminRequest
     */
    private void updateRevokeInfo(AdminRequest adminRequest) {
        Example example = new Example(AdminRequest.class);
        Example.Criteria sec = example.createCriteria();
        sec.andEqualTo("requestNo", adminRequest.getRequestNo());
        sec.andEqualTo("token", adminRequest.getToken());
        adminMapper.updateByExampleSelective(adminRequest, example);
    }


    /**
     * 回退到指定版本
     *
     * @param adminReq
     * @param adminRequest
     * @param version      回退到指定的版本号
     * @return
     */
    private CommonResult revokeToCustomVersion(AdminReq adminReq, AdminRequest adminRequest, Integer version) throws Exception {
        // 获取合同地址
        CommonResult commonResult = getContractPath(adminRequest);
        if (!commonResult.getIsSuccess()) {
            return new CommonResult(false, ResponseUtil.getResponseMessageData((Integer) commonResult.getResult(), null));
        }
        String downloadPath = commonResult.getResult().toString();
        String requestNo = adminRequest.getRequestNo();
        String token = adminRequest.getToken();
        String destPath = getSignSnapPDFPath(signPDFPath, requestNo);

        // 开始签章
        CFCASignResult cfcaSignResult = signContractToCustomVersion(adminReq, adminRequest, version, downloadPath, destPath);
        if (!cfcaSignResult.getIsSuccess()) {
            // 返回结果
            return new CommonResult(false, cfcaSignResult.getResultMsg());
        }
        destPath = cfcaSignResult.getResultMsg();

        // 获取返回压缩图片流
        String sealId = adminRequest.getSealId();
        CommonResult imageResult = getImages(requestNo, sealId);
        if (!imageResult.getIsSuccess()) {
            int code = (int) imageResult.getResult();
            return new CommonResult(false, ResponseUtil.getResponseMessageData(code, null));
        }

        HashMap data = new HashMap(16);
        data.put("fileUrl", buildWebFileUrl(requestNo, destPath));
        data.put("requestNo", requestNo);
        data.put("version", version - 1);
        data.put("token", token);
        data.put("sealImgs", imageResult.getResult());
        data.put("reSign", 1);

        // 删除以前的合同文件
        removeUnusedFile(requestNo, downloadPath, destPath);

        // 更新数据库数据
        updateRevokeData(adminRequest, version);

        return new CommonResult(true, data);
    }

    /**
     * 更新数据
     *
     * @param adminRequest
     * @param version
     */
    private void updateRevokeData(AdminRequest adminRequest, Integer version) {
        String versionInfo = adminRequest.getVersionInfo();
        if (StringUtils.isNotEmpty(versionInfo)) {
            JSONArray jsonArray = JSONObject.parseArray(versionInfo);
            List<Map> listMap = JSONObject.parseArray(jsonArray.toJSONString(), Map.class);
            ListIterator<Map> mapListIterator = listMap.listIterator();
            while (mapListIterator.hasNext()) {
                Map next = mapListIterator.next();
                Set<String> set = next.keySet();
                Integer keyVersion = Integer.valueOf(set.iterator().next());
                if (keyVersion > version) {
                    mapListIterator.remove();
                }
            }
            String newVersionInfo = JSONObject.toJSONString(listMap);
            adminRequest.setVersionInfo(newVersionInfo);
            adminRequest.setVersion(version);
            updateRevokeInfo(adminRequest);
        }
    }

    /**
     * 进行版本回退
     *
     * @param adminReq
     * @param adminRequest
     * @param version
     * @param downloadPath
     * @param destPath
     * @return
     */
    private CFCASignResult signContractToCustomVersion(AdminReq adminReq, AdminRequest adminRequest, Integer version, String downloadPath, String destPath) throws Exception {
        String versionInfo = adminRequest.getVersionInfo();
        JSONArray jsonArray = (JSONArray) JSON.parse(versionInfo);
        String sealId = adminRequest.getSealId();
        String requestNo = adminRequest.getRequestNo();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject object = (JSONObject) jsonArray.get(i);
            Iterator<String> iterator = object.keySet().iterator();
            String next = iterator.next();
            Integer tempVersion = Integer.valueOf(next);
            if (tempVersion > version) {
                break;
            }
            JSONObject object1 = object.getJSONObject(next);
            String style = object1.getString("style");
            if ("coordinate".equals(style)) {
                String pageNum = object1.getString("pageNum");
                String coordinateX = object1.getString("coordinate-X");
                String coordinateY = object1.getString("coordinate-Y");
                // 调用公章|合同章方法
                AdminReq adminReq2 = new AdminReq();
                adminReq2.setRequestNo(requestNo);
                adminReq2.setCoordinate(coordinateX + "," + coordinateY);
                adminReq2.setSealId(sealId);
                adminReq2.setPageNos(pageNum);
                String tempSignPath = getSignSnapPDFPath(signPDFPath, UUIDUtil.getUUID());
                CFCASignResult result = processContractSeal(adminReq2, downloadPath, tempSignPath);
                if (!result.getIsSuccess()) {
                    return result;
                }
                removeUnusedFile(adminReq.getRequestNo(), downloadPath, null);
                downloadPath = tempSignPath;
            }
            if ("paging".equals(style)) {
                String pageNum = object1.getString("pageNum");
                String pagingStyle = object1.getString("pagingStyle");
                Integer offsetY = Integer.valueOf(object1.getString("offsetY"));
                AdminReq adminReq3 = new AdminReq();
                adminReq3.setRequestNo(requestNo);
                adminReq3.setSealId(sealId);
                adminReq3.setPageNos2(pageNum);
                adminReq3.setPagingStyle(pagingStyle);
                adminReq3.setOffsetY(offsetY);
                String tempSignPath = getSignSnapPDFPath(signPDFPath, UUIDUtil.getUUID());
                // 骑缝章方法
                CFCASignResult result = processAcrossPageSeal(adminReq3, downloadPath, tempSignPath);
                if (!result.getIsSuccess()) {
                    return result;
                }
                removeUnusedFile(adminReq.getRequestNo(), downloadPath, null);
                downloadPath = tempSignPath;
            }
        }
        destPath = downloadPath;
        return new CFCASignResult(true, destPath);
    }

    /**
     * 获取合同文件
     *
     * @param adminRequest
     * @return
     */
    private CommonResult getContractPath(AdminRequest adminRequest) {
        // 下载合同
        String downloadPath = downloadContract(adminRequest.getRequestNo(), adminRequest.getDownloadFileUrl(), adminRequest.getSystemSign());
        if (StringUtils.isEmpty(downloadPath)) {
            return new CommonResult(false, ResponseEnum.GET_CONTRACT_FAILED.getCode());
        }
        // 校验合同是否可用
        boolean result = verifyPdfContract(downloadPath);
        if (!result) {
            return new CommonResult(false, ResponseEnum.INVALID_CONTRACT.getCode());
        }
        return new CommonResult(true, downloadPath);
    }

    /**
     * 获取AdminRequest
     *
     * @param requestNo
     * @param token
     * @return
     */
    private AdminRequest getAdminRequest(String requestNo, String token) {
        Example se = new Example(AdminRequest.class);
        Example.Criteria sec = se.createCriteria();
        sec.andEqualTo("requestNo", requestNo);
        sec.andEqualTo("token", token);
        return adminMapper.selectOneByExample(se);
    }

    /**
     * 手动签章核心处理方法
     * 首次签章时：fileUrl字段为空，签章成功后返回给前端
     * 版本回退之后签章时，fileUrl不为空
     *
     * @param adminReq
     * @return
     */
    @Override
    public Object invoke(AdminReq adminReq) throws Exception {
        String requestNo = adminReq.getRequestNo();
        String token = adminReq.getToken();

        // 根据requestNo、token查询数据库记录信息
        AdminRequest adminRequest = getAdminRequest(requestNo, token);
        if (adminRequest == null) {
            return new CommonResult(false, ResponseEnum.ILLEGAL_REQUESTNO.getCode());
        }

        String sourcePath = null;
        String destPath = getSignSnapPDFPath(signPDFPath, requestNo);
        Integer version = 0;
        // 获取合同文件
        if (adminReq.getReSign() == 0) {
            CommonResult commonResult = getContractPath(adminRequest);
            if (!commonResult.getIsSuccess()) {
                return new CommonResult(false, ResponseUtil.getResponseMessageData((Integer) commonResult.getResult(), null));
            }
            sourcePath = commonResult.getResult().toString();
            // 记录版本信息，用于版本回退
            version = recordVersionInfo(adminReq, false);
        } else {
            String fileUrl = adminReq.getFileUrl();
            String tempFilePath = fileUrl.replace(WEB_PDF_URL_PREFIX, WEB_PDF_FOLDER_PATH);
            sourcePath = getSignSnapPDFPath(signPDFPath, requestNo);
            copyFile(requestNo, tempFilePath, sourcePath);
            // 记录版本信息，用于版本回退
            version = recordVersionInfo(adminReq, true);
        }

        // 开始签章
        CFCASignResult cfcaSignResult = signContract(adminReq, sourcePath, destPath);

        // 解析请求结果
        String callbackUrl = adminRequest.getCallbackUrl();
        String systemSign = adminRequest.getSystemSign();
        if (!cfcaSignResult.getIsSuccess()) {
            return hanleFailResult(requestNo, token, callbackUrl, cfcaSignResult);
        }
        return hanleSuccessResult(requestNo, token, version, systemSign, callbackUrl, sourcePath, destPath, cfcaSignResult);
    }

    /**
     * 处理签章成功结果
     *
     * @param requestNo
     * @param token
     * @param version
     * @param systemSign
     * @param callbackUrl
     * @param sourcePath
     * @param destPath
     * @param cfcaSignResult
     * @return
     */
    private Object hanleSuccessResult(String requestNo, String token, Integer version, String systemSign, String callbackUrl, String sourcePath, String destPath, CFCASignResult cfcaSignResult) {
        // 上传合同文件到文件服务器
        String fileId = uploadContractFile(requestNo, systemSign, destPath);
        // 异步回调业务系统
        futureService.callbackBusiness(requestNo, token, callbackUrl, true, "合同签章成功", fileId);
        // 更新数据库
        updateRequestData(requestNo, token, SignStatusConstant.SUCCESS, cfcaSignResult.getResultMsg(), fileId);
        // 同步返回结果
        HashMap data = new HashMap(16);
        data.put("fileUrl", buildWebFileUrl(requestNo, destPath));
        data.put("requestNo", requestNo);
        data.put("version", version - 1);
        data.put("token", token);
        data.put("reSign", 0);

        // 删除以前的合同文件
        removeUnusedFile(requestNo, sourcePath, destPath);
        return ResponseUtil.getResponseMessageData(ResponseEnum.SIGN_SUCCESS.getCode(), data);
    }

    /**
     * 处理签章失败结果
     *
     * @param requestNo
     * @param token
     * @param callbackUrl
     * @param cfcaSignResult
     * @return
     */
    private Object hanleFailResult(String requestNo, String token, String callbackUrl, CFCASignResult cfcaSignResult) {
        log.error("行政章接口-->－消息－:requestSn={},签章结果:{}", requestNo, cfcaSignResult.getResultMsg());
        // 更新数据库
        updateRequestData(requestNo, token, SignStatusConstant.FAILED, cfcaSignResult.getResultMsg(), null);
        // 异步回调业务系统
        futureService.callbackBusiness(requestNo, token, callbackUrl, false, cfcaSignResult.getResultMsg(), null);
        // 同步返回结果
        HashMap data = new HashMap();
        data.put("requestNo", requestNo);
        data.put("errorMsg", cfcaSignResult.getResultMsg());
        return ResponseUtil.getResponseMessageData(ResponseEnum.SIGN_FAILED.getCode(), data);
    }

    /**
     * 记录版本相关信息
     *
     * @param adminReq
     */
    private Integer recordVersionInfo(AdminReq adminReq, boolean reSign) {
        String requestNo = adminReq.getRequestNo();
        String token = adminReq.getToken();
        String sealType = adminReq.getSealType();
        AdminRequest adminRequest = getAdminRequest(requestNo, token);
        if (reSign) {
            String versionInfo = adminRequest.getVersionInfo();
            adminRequest.setVersionInfo(buildVersionInfo(1, adminReq, versionInfo));
        } else {
            adminRequest.setVersionInfo(buildVersionInfo(1, adminReq, null));
        }
        adminRequest.setVersion(adminReq.getVersion());
        adminRequest.setSealType(sealType);
        adminRequest.setUpdateTime(new Date());

        Example example = new Example(AdminRequest.class);
        Example.Criteria sec = example.createCriteria();
        sec.andEqualTo("requestNo", requestNo);
        sec.andEqualTo("token", token);
        adminMapper.updateByExampleSelective(adminRequest, example);
        return adminRequest.getVersion();
    }

    /**
     * 构建versionInfo信息
     *
     * @param versionNum
     * @param adminReq
     * @param appendVersionInfo
     * @return
     */
    private String buildVersionInfo(int versionNum, AdminReq adminReq, String appendVersionInfo) {
        List<Map> versionInfo = new ArrayList();
        // 如果不为空，追加到versionInfo中
        if (StringUtils.isNotEmpty(appendVersionInfo)) {
            JSONArray jsonArray = JSONObject.parseArray(appendVersionInfo);
            List<Map> listMap = JSONObject.parseArray(jsonArray.toJSONString(), Map.class);
            versionInfo.addAll(listMap);
            versionNum = listMap.size() + 1;
        }

        // 设置坐标章信息
        String sealType = adminReq.getSealType();
        if (SealInfoConstant.CONTRACT_SEAL.equals(sealType)) {
            versionNum = buildContractSealInfo(versionNum, adminReq, versionInfo);
        }
        // 设置骑缝章信息
        if (SealInfoConstant.ACROSSPAGE_SEAL.equals(sealType)) {
            versionNum = buildAcrossSealInfo(versionNum, adminReq, versionInfo);
        }
        // 设置坐标章信息+骑缝章信息
        if (SealInfoConstant.ALL.equals(sealType)) {
            versionNum = buildContractSealInfo(versionNum, adminReq, versionInfo);
            versionNum = buildAcrossSealInfo(versionNum, adminReq, versionInfo);
        }

        adminReq.setVersion(versionNum);
        return JSON.toJSONString(versionInfo);
    }

    /**
     * 设置骑缝章信息
     *
     * @param versionNum
     * @param adminReq
     * @param versionInfo
     * @return
     */
    private int buildAcrossSealInfo(int versionNum, AdminReq adminReq, List<Map> versionInfo) {
        String pageNos2 = adminReq.getPageNos2();
        Map hashMap = new HashMap();
        JSONObject object = new JSONObject();
        // 签章类型
        object.put("style", SealInfoConstant.ACROSSPAGE_SEAL);
        // 签章页码
        object.put("pageNum", pageNos2);
        // 签章坐标
        Integer offsetY = adminReq.getOffsetY();
        object.put("offsetY", offsetY);
        // 签章样式
        object.put("pagingStyle", adminReq.getPagingStyle());
        // 版本号
        versionNum++;
        hashMap.put(String.valueOf(versionNum), object);
        versionInfo.add(hashMap);
        return versionNum;
    }

    /**
     * 设置坐标章信息
     *
     * @param versionNum
     * @param adminReq
     * @param versionInfo
     * @return
     */
    private int buildContractSealInfo(int versionNum, AdminReq adminReq, List<Map> versionInfo) {
        String pageNos = adminReq.getPageNos();
        String[] split = pageNos.split(",");
        for (String s : split) {
            Map hashMap = new HashMap();
            JSONObject object = new JSONObject();
            // 签章类型
            object.put("style", SealInfoConstant.CONTRACT_SEAL);
            // 签章页码
            object.put("pageNum", s);
            // 签章坐标
            String coordinate = adminReq.getCoordinate();
            String[] split2 = coordinate.split(",");
            Integer XAxis = Integer.valueOf(split2[0]);
            Integer YAxis = Integer.valueOf(split2[1]);
            object.put("coordinate-X", XAxis);
            object.put("coordinate-Y", YAxis);
            // 版本号
            versionNum++;
            hashMap.put(String.valueOf(versionNum), object);
            versionInfo.add(hashMap);
        }
        return versionNum;
    }

    /**
     * 执行签章方法
     *
     * @param adminReq
     * @param sourcePath
     * @param destPath
     * @return
     */
    private CFCASignResult signContract(AdminReq adminReq, String sourcePath, String destPath) throws Exception {
        // 设置PDF旋转
        if (adminReq.getRotation() != null && adminReq.getRotation().intValue() != 0) {
            String namex = getSignSnapPDFPath(noSignPDFPath, UUIDUtil.getUUID());
            PdfRotationUtil.rotatingAngel(adminReq.getRotation(), sourcePath, namex);
            removeUnusedFile(adminReq.getRequestNo(), sourcePath, null);
            sourcePath = namex;
        }

        CFCASignResult cfcaSignResult = null;
        try {
            String sealType = adminReq.getSealType();
            if (sealType.equals(SealInfoConstant.CONTRACT_SEAL)) {
                //合同章/公章
                cfcaSignResult = processContractSeal(adminReq, sourcePath, destPath);
                if (!cfcaSignResult.getIsSuccess()) {
                    throw new Exception(cfcaSignResult.getResultMsg());
                }
            } else if (sealType.equals(SealInfoConstant.ACROSSPAGE_SEAL)) {
                //骑缝章
                cfcaSignResult = processAcrossPageSeal(adminReq, sourcePath, destPath);
                if (!cfcaSignResult.getIsSuccess()) {
                    throw new Exception(cfcaSignResult.getResultMsg());
                }
            } else {
                //合同章/公章 + 骑缝章
                cfcaSignResult = processMultipleSeal(adminReq, sourcePath, destPath);
                if (!cfcaSignResult.getIsSuccess()) {
                    throw new Exception(cfcaSignResult.getResultMsg());
                }
            }
        } catch (Exception e) {
            log.error("行政章接口-->－消息－:requestSn={},执行签章方法发生异常......", adminReq.getRequestNo(), e);
        }
        return cfcaSignResult;
    }

    /**
     * 校验合同是否可用
     *
     * @param downloadPath
     * @return
     */
    private boolean verifyPdfContract(String downloadPath) {
        try {
            PdfReader pdfReader = new PdfReader(downloadPath);
            PdfTextExtractor.getTextFromPage(pdfReader, 1);
            pdfReader.close();
            return true;
        } catch (IOException e) {
            return false;
        } finally {
        }
    }

    /**
     * 封装返回前端文件地址
     *
     * @param requestNo
     * @param destPath
     * @return
     */
    private String buildWebFileUrl(String requestNo, String destPath) {
        File sourceFile = new File(destPath);
        try {
            if (sourceFile.exists()) {
                String name = getSimplePdfName(UUIDUtil.getUUID());
                String destFilePath = WEB_PDF_FOLDER_PATH + name;
                Files.createParentDirs(new File(destFilePath));
                File toFile = new File(destFilePath);
                Files.copy(sourceFile, toFile);
                return WEB_PDF_URL_PREFIX + name;
            }
            return null;
        } catch (Exception e) {
            log.error("行政章【签章接口】-->－消息－:requestSn={},拷贝文件失败,请检查......", requestNo, e);
            return null;
        }
    }

    /**
     * 拷贝分件
     *
     * @param sourcePath
     * @param destPath
     * @return
     */
    private boolean copyFile(String requestNo, String sourcePath, String destPath) {
        if (sourcePath.contains(WEB_PDF_URL_PREFIX)) {
            sourcePath = sourcePath.replace(WEB_PDF_URL_PREFIX, WEB_PDF_FOLDER_PATH);
        }

        File sourceFile = new File(sourcePath);
        try {
            if (sourceFile.exists()) {
                File toFile = new File(destPath);
                Files.copy(sourceFile, toFile);
                return true;
            }
            return false;
        } catch (Exception e) {
            log.error("行政章【版本回退接口】-->－消息－:requestSn={},拷贝文件失败,请检查......", requestNo, e);
            return false;
        }
    }

    /**
     * 上传文件
     *
     * @param requestNo
     * @param systemSign
     * @param destPath
     * @return
     */
    private String uploadContractFile(String requestNo, String systemSign, String destPath) {
        log.info("----------------------------------------");
        String fileId = null;
        String fileName = UUIDUtil.getUUID();
        log.debug("行政章接口-->－消息－:requestSn={},systemSign={},上传合同文件地址:{}", requestNo, systemSign, destPath);
        try {
            Date date = new Date();
            if(systemSign.equalsIgnoreCase(SealInfoConstant.JFLOW)){
                File file = new File(destPath);
                boolean result = AmazonUtil.uploadToS3(file, fileName);
                if (result) {
                    fileId = fileName;
                }
            }else {
                File file = new File(destPath);
                boolean result = AmazonUtil2.uploadToS3(file, fileName);
                if (result) {
                    fileId = fileName;
                }
            }
            log.info("行政章接口-->－消息－:requestSn={},上传合同文件成功......耗时:{}秒", requestNo, DateUtil.betweenNowSecond(date));
        } catch (Exception e) {
            log.info("行政章接口-->－消息－:requestSn={},上传合同文件失败......{}", requestNo, e.getMessage());
        }
        return fileId;
    }

    /**
     * 更新数据库状态
     *
     * @param requestNo
     * @param token
     * @param signStatus
     * @param resultMsg
     * @param fileId
     */
    private void updateRequestData(String requestNo, String token, Integer signStatus, String resultMsg, String fileId) {
        Example se = new Example(AdminRequest.class);
        Example.Criteria sec = se.createCriteria();
        sec.andEqualTo("requestNo", requestNo);
        sec.andEqualTo("token", token);
        AdminRequest adminRequest = new AdminRequest();
        adminRequest.setUpdateTime(new Date());
        adminRequest.setSignStatus(signStatus);
        adminRequest.setSignResult(resultMsg);
        if (StringUtils.isNotEmpty(fileId)) {
            adminRequest.setUploadFileUrl(fileId);
        }
        adminMapper.updateByExampleSelective(adminRequest, se);
    }

    /**
     * 处理合同章/公章 + 骑缝章
     *
     * @param adminReq
     * @param sourcePath
     * @return
     */
    private CFCASignResult processMultipleSeal(AdminReq adminReq, String sourcePath, String destPath) {
        try {
            // 1.先处理：合同章/公章
            processContractSeal(adminReq, sourcePath, destPath);

            // 2.再处理：骑缝章
            processAcrossPageSeal(adminReq, destPath, destPath);
        } catch (Exception e) {
            log.error("行政章接口-->－消息－:requestSn={},处理[合同章/公章 + 骑缝章]方法发生异常", e);
            return new CFCASignResult(false, e.getMessage());
        }
        return new CFCASignResult(true, "合同签章成功");
    }

    /**
     * 骑缝章
     *
     * @param adminReq
     * @param sourcePath
     * @param destPath
     * @return
     */
    private CFCASignResult processAcrossPageSeal(AdminReq adminReq, String sourcePath, String destPath) throws Exception {
        log.info("行政章接口-->－消息－:requestSn={},开始制作[骑缝章]......", adminReq.getRequestNo());
        SealClient client = new SealClient(sealUrl);
        CrossPageSealInfo crossPageSealInfo = new CrossPageSealInfo();
        String sealCode = adminReq.getSealId();
        // 查询是否配置了骑缝章
        if (StringUtil.isNotEmpty(sealCode)){
            SealInfo sealInfo = sealInfoMapper.selectBySealCode(sealCode);
            SealInfo tempSealInfo = new SealInfo();
            tempSealInfo.setKeyWords(sealInfo.getKeyWords());
            tempSealInfo.setOfficeSealType(6);
            SealInfo info = sealInfoMapper.selectOne(tempSealInfo);
            if(info != null){
                sealCode = info.getSealCode();
            }
        }
        String pageNos2 = adminReq.getPageNos2();
        String pagingStyle = adminReq.getPagingStyle();
        if (StringUtils.isEmpty(pagingStyle)) {
            pagingStyle = "6";
        }
        Integer offsetY = adminReq.getOffsetY();
        if (offsetY == null) {
            offsetY = 0;
        }
        SealInfo sealInfo = sealInfoMapper.selectBySealCode(sealCode);
        if (sealInfo == null) {
            return new CFCASignResult(false, "公章编号：[" + sealCode + "]的公章不存在");
        }

        crossPageSealInfo.setSealCode(sealCode);
        crossPageSealInfo.setSealPwd(sealInfo.getSealPwd());
        crossPageSealInfo.setKeyWords(sealInfo.getKeyWords());
        crossPageSealInfo.setFromPage("1");
        crossPageSealInfo.setToPage(pageNos2);
        crossPageSealInfo.setCrossStyle(pagingStyle);
        crossPageSealInfo.setOffsetY(offsetY);

        Date date = new Date();
        byte[] pdfData = FileUtil.getBytesFromFile(new File(sourcePath));
        log.info("行政章接口-->－消息－:requestSn={},骑缝章方法[获取合同文件流]耗时：{}秒", adminReq.getRequestNo(), DateUtil.betweenNowSecond(date));
        String sealStrategyXML = buildCrossPageSealXmlParams(crossPageSealInfo);

        try {
            Date date2 = new Date();
            byte[] resultData = client.sealAutoCrossPdf(pdfData, sealStrategyXML);
            log.info("行政章接口-->－消息－:requestSn={},骑缝章方法调用Seal服务[执行骑缝章]耗时：{}秒", adminReq.getRequestNo(), DateUtil.betweenNowSecond(date2));
            //解析返回结果
            CFCASignResult cfcaSignResult = getCfcaSignResult(adminReq.getRequestNo(), resultData);
            if (cfcaSignResult != null) {
                return cfcaSignResult;
            }
            Date date3 = new Date();
            FileUtil.wirteDataToFile(destPath, resultData);
            log.info("行政章接口-->－消息－:requestSn={},骑缝章方法将签章后[合同文件流写入本地]耗时：{}秒", adminReq.getRequestNo(), DateUtil.betweenNowSecond(date3));
        } catch (Exception e) {
            log.error("行政章接口-->－消息－:requestSn={} 调用三方接口发生异常", adminReq.getRequestNo(), e);
            return new CFCASignResult(false, e.getMessage());
        }
        log.info("行政章接口-->－消息－:requestSn={},制作[骑缝章]完成......", adminReq.getRequestNo());
        return new CFCASignResult(true, "合同签章成功");
    }

    /**
     * 合同章/公章
     *
     * @param adminReq
     * @param sourcePath
     * @param destPath
     * @return null
     */
    private CFCASignResult processContractSeal(AdminReq adminReq, String sourcePath, String destPath) throws Exception {
        log.info("行政章接口-->－消息－:requestSn={},开始制作[合同章/公章]......", adminReq.getRequestNo());
        SealClient client = new SealClient(sealUrl);
        ContractSealInfo contractSealInfo = new ContractSealInfo();

        SealInfo sealInfo = sealInfoMapper.selectBySealCode(adminReq.getSealId());
        if (sealInfo == null) {
            return new CFCASignResult(false, "公章编号：[" + adminReq.getSealId() + "]的公章不存在");
        }

        String coordinate = adminReq.getCoordinate();
        String[] split = coordinate.split(",");
        Integer XAxis = Integer.valueOf(split[0]);
        Integer YAxis = Integer.valueOf(split[1]);
        log.info("行政章接口-->－消息－:requestSn={},合同章/公章[盖章坐标：X轴={},Y轴={}]", adminReq.getRequestNo(), XAxis, YAxis);
        contractSealInfo.setSealCode(adminReq.getSealId());
        contractSealInfo.setLeftX(XAxis);
        contractSealInfo.setLeftY(YAxis);
        contractSealInfo.setPage(adminReq.getPageNos());
        contractSealInfo.setSealPwd(sealInfo.getSealPwd());
        contractSealInfo.setKeyWords(sealInfo.getKeyWords());


        Date date = new Date();
        byte[] pdfData = FileUtil.getBytesFromFile(new File(sourcePath));
        log.info("行政章接口-->－消息－:requestSn={},合同章/公章方法[获取合同文件流]耗时：{}秒", adminReq.getRequestNo(), DateUtil.betweenNowSecond(date));
        String sealStrategyXML = buildContractSealXmlParams(contractSealInfo);

        try {
            Date date2 = new Date();
            byte[] resultData = client.sealAutoPdf(pdfData, sealStrategyXML);
            log.info("行政章接口-->－消息－:requestSn={},合同章/公章方法调用Seal服务[执行合同章/公章]耗时：{}秒", adminReq.getRequestNo(), DateUtil.betweenNowSecond(date2));
            //解析返回结果
            CFCASignResult cfcaSignResult = getCfcaSignResult(adminReq.getRequestNo(), resultData);
            if (cfcaSignResult != null) {
                return cfcaSignResult;
            }
            Date date3 = new Date();
            FileUtil.wirteDataToFile(destPath, resultData);
            log.info("行政章接口-->－消息－:requestSn={},合同章/公章方法将签章后[合同文件流写入本地]耗时：{}秒", adminReq.getRequestNo(), DateUtil.betweenNowSecond(date3));
        } catch (Exception e) {
            log.error("行政章接口-->－消息－:requestSn={},调用三方接口发生异常", adminReq.getRequestNo(), e);
            return new CFCASignResult(false, e.getMessage());
        }

        log.info("行政章接口-->－消息－:requestSn={},制作[合同章/公章]完成......", adminReq.getRequestNo());
        return new CFCASignResult(true, "合同签章成功");
    }

    /**
     * 解析接口返回结果
     *
     * @param requestNo
     * @param resultData
     * @return
     */
    private CFCASignResult getCfcaSignResult(String requestNo, byte[] resultData) {
        if (!StringUtil.checkResultDataValid(resultData)) {
            String wrongMsg = new String(resultData, StandardCharsets.UTF_8);
            String errorMsg = StringUtil.getNodeText(wrongMsg, CoreConstant.CFCA_ERROR_MSG);
            log.error("行政章接口-->－消息－:requestSn={},调用三方接口返回异常信息:{}", requestNo, errorMsg);
            return new CFCASignResult(false, errorMsg);
        }
        return null;
    }

    /**
     * 封装骑缝章请求参数
     *
     * @param crossPageSealInfo
     * @return
     */
    private String buildCrossPageSealXmlParams(CrossPageSealInfo crossPageSealInfo) {
        //准备请求参数
        String sealCode = crossPageSealInfo.getSealCode();
        // 骑缝章风格-->1：上下各一半2：左右各一半3：上下骑缝4：左右骑缝5：左骑缝6：右骑缝
        String crossStyle = crossPageSealInfo.getCrossStyle();
        // 起始页
        String fromPage = crossPageSealInfo.getFromPage();
        // 结束页
        String toPage = crossPageSealInfo.getToPage();
        String sealPassword = crossPageSealInfo.getSealPwd();
        String sealPerson = SealParamsConstant.SEALPERSON;
        String sealLocation = crossPageSealInfo.getKeyWords();
        String sealReason = SealParamsConstant.SEALREASON;

        SealUserInfo sealUserInfo = new SealUserInfo(sealPerson, sealLocation, sealReason);
        CrossSealInfoBean crossSealInfoBean = new CrossSealInfoBean(sealCode, sealPassword, fromPage, toPage, crossStyle, sealUserInfo);
        crossSealInfoBean.setOffsetY(crossPageSealInfo.getOffsetY());
        return StrategyUtil.createCrossSealStrategyXML(crossSealInfoBean);
    }

    /**
     * 封装合同章/公章请求参数
     *
     * @param contractSealInfo
     * @return
     * @throws Exception
     */
    private String buildContractSealXmlParams(ContractSealInfo contractSealInfo) throws Exception {
        //准备请求参数
        int leftX = contractSealInfo.getLeftX();
        int leftY = contractSealInfo.getLeftY();
        // 支持（1）单页，（1,2,3,4）多页,（1-3）区间，（0）所有页
        String page = contractSealInfo.getPage();
        String sealPassword = contractSealInfo.getSealPwd();
        String sealPerson = SealParamsConstant.SEALPERSON;
        String sealLocation = contractSealInfo.getKeyWords();
        String sealReason = SealParamsConstant.SEALREASON;
        String businessCode = SealParamsConstant.BUSINESS_CODE;
        String businessCodeStyle = SealParamsConstant.BUSINESSCODESTYLE;

        SealUserInfo sealUserInfo = new SealUserInfo(sealPerson, sealLocation, sealReason);
        SignLocation signLocation = new SignLocation(page, leftX, leftY);
        return StrategyUtil.createSealStrategyXml(contractSealInfo.getSealCode(), sealPassword, businessCode, businessCodeStyle, sealUserInfo, signLocation);
    }

    /**
     * 删除不使用的文件
     *
     * @param requestNo
     * @param sourcePath
     * @param destPath
     */
    public void removeUnusedFile(String requestNo, String sourcePath, String destPath) {
        String filePath = null;
        try {
            if (StringUtils.isNotEmpty(sourcePath)) {
                filePath = sourcePath;
                File file = new File(sourcePath);
                if (file.exists()) {
                    file.delete();
                    log.info("行政章接口-->－消息－:requestSn={},删除不使用的文件成功,合同路径：{}", requestNo, sourcePath);
                }
            }
            if (StringUtils.isNotEmpty(destPath)) {
                filePath = destPath;
                File file = new File(destPath);
                if (file.exists()) {
                    file.delete();
                    log.info("行政章接口-->－消息－:requestSn={},删除不使用的文件成功,合同路径：{}", requestNo, destPath);
                }
            }
        } catch (Exception e) {
            log.error("行政章接口-->－消息－:requestSn={},删除不使用的文件失败,合同路径：{}", requestNo, filePath, e);
        }
    }

    /**
     * 下载PDF合同文件
     *
     * @param requestNo
     * @param fileName
     * @param systemSign
     * @return
     */
    public String downloadContract(String requestNo, String fileName, String systemSign) {
        log.info("----------------------------------------");
        String downloadPath = null;
        String snapPDFPath = getSignSnapPDFPath(noSignPDFPath, requestNo);
        log.debug("行政章接口-->－消息－:requestSn={},systemSign={},下载合同文件地址:{}", requestNo, systemSign, snapPDFPath);
        Date date = new Date();
        try {
            if(systemSign.equalsIgnoreCase(SealInfoConstant.JFLOW)){
                AmazonUtil.downFromS3(fileName, snapPDFPath);
            }else {
                AmazonUtil2.downFromS3(fileName, snapPDFPath);
            }
            downloadPath = snapPDFPath;
            log.info("行政章接口-->－消息－:requestSn={},合同文件下载成功......{},耗时:{}秒", requestNo, snapPDFPath, DateUtil.betweenNowSecond(date));
        } catch (Exception e) {
            log.info("行政章接口-->－消息－:requestSn={},合同文件下载失败......{}", requestNo, e.getMessage());
        }
        return downloadPath;
    }

    /**
     * 保存请求流水
     *
     * @param adminReq
     */
    public void saveRequestData(AdminReq adminReq) {
        AdminRequest adminRequest = new AdminRequest();
        BeanUtils.copyProperties(adminReq, adminRequest);
        adminRequest.setSysKey(SEQUENCE_KEY);
        adminRequest.setToken(adminReq.getToken());
        adminRequest.setDownloadFileUrl(adminReq.getFileUrl());
        adminRequest.setFileSys(adminReq.getFileSys());
        adminRequest.setCreatTime(new Date());
        adminRequest.setSignStatus(SignStatusConstant.NONE_PROCESS);
        adminMapper.insertSelective(adminRequest);
    }

    /**
     * 获取要签章pdf文件路径
     *
     * @param requestNo
     * @return
     */
    public String getSignSnapPDFPath(String dirPath, String requestNo) {
        String pdfName = SNAP_PDF_PREFIX + requestNo + PDF_EXT;
        String date = DateUtil.getStandardDateStr();
        File snapFolder = new File(dirPath + File.separator + date);
        if (!snapFolder.exists()) {
            snapFolder.mkdirs();
        }
        return dirPath + File.separator + date + File.separator + pdfName;
    }

    /**
     * 获取PDF文件名字
     *
     * @param requestNo
     * @return
     */
    public String getSimplePdfName(String requestNo) {
        return SNAP_PDF_PREFIX + requestNo + PDF_EXT;
    }

    /**
     * 获取返回参数
     *
     * @param adminReq
     * @return
     */
    @Override
    public Object adminVerify(AdminReq adminReq) {
        // 保存请求流水
        String token = UUIDUtil.getUUID();
        adminReq.setToken(token);
        saveRequestData(adminReq);

        // 封装印章图片
        String sealId = adminReq.getSealId();
        String requestNo = adminReq.getRequestNo();
        CommonResult imageResult = getImages(requestNo, sealId);
        if (!imageResult.getIsSuccess()) {
            int code = (int) imageResult.getResult();
            return ResponseUtil.getResponseMessageData(code, null);
        }

        // 下载合同文件
        String downloadPath = downloadContract(adminReq.getRequestNo(), adminReq.getFileUrl(), adminReq.getSystemSign());

        // 返回结果
        HashMap data = new HashMap();
        data.put("requestNo", requestNo);
        data.put("token", token);
        data.put("fileUrl", buildWebFileUrl(adminReq.getRequestNo(), downloadPath));
        data.put("sealImgs", imageResult.getResult());
        data.put("reSign", 0);

        // TODO 删除/data/temp/S3/目录下临时文件
        return ResponseUtil.getResponseMessageData(ResponseEnum.VERIFY_SUCCESS.getCode(), data);
    }

    /**
     * 获取压缩图片流
     *
     * @param requestNo
     * @param sealId
     * @return
     */
    private CommonResult getImages(String requestNo, String sealId) {
        String[] split = sealId.split(",");
        JSONArray array = new JSONArray();
        for (String id : split) {
            try {
                SealInfo sealInfo = sealInfoMapper.selectBySealCode(id);
                if (sealInfo == null) {
                    int code = ResponseEnum.GET_PICTURE_FAILED.getCode();
                    return new CommonResult(false, code);
                }
                byte[] imageData = sealInfo.getImage();

                // 将图片缩放
                imageData = scaleImage(imageData, requestNo);

                // 将图片转成base64格式
                String imageBase64 = "data:image/png;base64," + Base64.encodeBase64String(imageData);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("sealId", id);
                jsonObject.put("sealImage", imageBase64);
                array.add(jsonObject);
            } catch (Exception e) {
                log.error("行政章接口-->－消息－:requestSn={},获取印章图片失败", requestNo, e);
                int code = ResponseEnum.GET_PICTURE_FAILED.getCode();
                return new CommonResult(false, code);
            }
        }
        log.info("行政章接口-->－消息－:requestSn={},返回压缩后图片流", requestNo);
        return new CommonResult(true, array);
    }

    /**
     * 缩放图片
     *
     * @param imageData
     * @return
     * @throws Exception
     */
    private byte[] scaleImage(byte[] imageData, String requestNo) {
        File imageFolder = new File(imagePath);
        if (!imageFolder.exists()) {
            imageFolder.mkdirs();
        }
        String imageSrcPath = imagePath + UUIDUtil.getUUID() + ".png";
        String imageDestPath = imagePath + UUIDUtil.getUUID() + ".png";
        String imageType = "png";
        try {
            FileUtil.wirteDataToFile(imageSrcPath, imageData);
            HashMap imageSize = getImageSize(imageSrcPath, imageType);
            int width = (int) imageSize.get("width");
            int height = (int) imageSize.get("height");

            writeImageData(imageSrcPath, imageDestPath, width, height, imageType);
            byte[] imageDate = FileUtil.getBytesFromFile(new File(imageDestPath));

            // 删除临时图片文件
            removeUnusedFile(requestNo, imageSrcPath, imageDestPath);
            return imageDate;
        } catch (Exception e) {
            log.error("行政章接口-->－消息－:requestSn={},缩放印章图片失败,返回原有尺寸图片流", requestNo, e);
            return imageData;
        }
    }

    /**
     * 将缩放图片保存到磁盘
     *
     * @param imageSrc
     * @param imageDest
     * @param width
     * @param height
     * @param imageType
     * @throws Exception
     */
    private static void writeImageData(String imageSrc, String imageDest, int width, int height, String imageType) throws Exception {
        int scaleWidth = 0;
        int scaleHeight = 0;
        if (width >= 170 && width <= 176) {
            scaleWidth = width - 5;
            scaleHeight = height - 5;
        } else if (width >= 180 && width <= 186) {
            scaleWidth = width - 10;
            scaleHeight = height - 10;
        } else if (width >= 250 && width <= 256) {
            scaleWidth = new Float(width * 0.94).intValue();
            scaleHeight = new Float(height * 0.94).intValue();
        } else if (width >= 350 && width <= 356) {
            scaleWidth = new Float(width * 0.5).intValue();
            scaleHeight = new Float(height * 0.5).intValue();
        } else {
            scaleWidth = width;
            scaleHeight = height;
        }
        log.info("image width :{} , height :{}", scaleWidth, scaleHeight);
        BufferedImage bufferedImage = new BufferedImage(scaleWidth, scaleHeight, BufferedImage.TYPE_INT_RGB);

        // 设置背景颜色透明
        BufferedImageGraphicsConfig config = BufferedImageGraphicsConfig.getConfig(bufferedImage);
        bufferedImage = config.createCompatibleImage(scaleWidth, scaleHeight, Transparency.TRANSLUCENT);

        // bufferedImage画板
        Graphics graphics = bufferedImage.getGraphics();

        //读取原始位图
        Image srcImage = ImageIO.read(new File(imageSrc));

        //将原始位图缩小后绘制到bufferedImage对象中
        graphics.drawImage(srcImage, 0, 0, scaleWidth, scaleHeight, null);

        //将bufferedImage对象输出到磁盘上
        ImageIO.write(bufferedImage, imageType, new File(imageDest));
    }

    /**
     * 获取图片的宽高
     *
     * @param imageSrc
     * @param imageType
     * @return
     * @throws Exception
     */
    private static HashMap getImageSize(String imageSrc, String imageType) throws Exception {
        ImageInputStream iis = null;
        try {
            Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName(imageType);
            ImageReader reader = (ImageReader) readers.next();
            File file = new File(imageSrc);
            iis = ImageIO.createImageInputStream(file);
            reader.setInput(iis, true);
            HashMap imageMap = new HashMap(16);
            imageMap.put("height", reader.getHeight(0));
            imageMap.put("width", reader.getHeight(0));
            return imageMap;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            iis.close();
        }
        return null;
    }

}
